Changeset 683 for trunk/kernel/kern/process.c
- Timestamp:
- Jan 13, 2021, 12:36:17 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/process.c
r669 r683 2 2 * process.c - process related functions definition. 3 3 * 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012)4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (2016,2017,2018,2019,2020)6 * Alain Greiner (2016,2017,2018,2019,2020) 7 7 * 8 8 * Copyright (c) UPMC Sorbonne Universites … … 70 70 ////////////////////////////////////////////////////////////////////////////////////////// 71 71 72 /////////////////////////////////73 process_t * process_alloc( void )74 {75 76 assert( __FUNCTION__, (sizeof(process_t) < CONFIG_PPM_PAGE_SIZE),77 "process descriptor exceeds 1 page" );78 79 kmem_req_t req;80 81 req.type = KMEM_PPM;82 req.order = 0;83 req.flags = AF_KERNEL | AF_ZERO;84 return kmem_alloc( &req );85 }86 87 ////////////////////////////////////////88 void process_free( process_t * process )89 {90 kmem_req_t req;91 92 req.type = KMEM_PPM;93 req.ptr = process;94 kmem_free( &req );95 }96 97 72 //////////////////////////////////////////////////// 98 73 error_t process_reference_init( process_t * process, … … 116 91 vmm_t * vmm; 117 92 118 // build extended pointer on this reference process 93 #if DEBUG_PROCESS_REFERENCE_INIT || DEBUG_PROCESS_ERROR 94 thread_t * this = CURRENT_THREAD; 95 uint32_t cycle = (uint32_t)hal_get_cycles(); 96 #endif 97 98 // build extended pointer on reference process 119 99 process_xp = XPTR( local_cxy , process ); 120 100 … … 130 110 131 111 #if DEBUG_PROCESS_REFERENCE_INIT 132 thread_t * this = CURRENT_THREAD;133 uint32_t cycle = (uint32_t)hal_get_cycles();134 112 if( DEBUG_PROCESS_REFERENCE_INIT < cycle ) 135 113 printk("\n[%s] thread[%x,%x] enter to initialize process %x / cycle %d\n", … … 156 134 if( error ) 157 135 { 158 printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ ); 136 137 #if DEBUG_PROCESS_ERROR 138 printk("\n[ERROR] in %s : thread[%x,%x] cannot create empty GPT / cycle %d\n", 139 __FUNCTION__, this->process->pid, this->trdid, cycle ); 140 #endif 159 141 return -1; 160 142 } … … 173 155 if( error ) 174 156 { 157 158 #if DEBUG_PROCESS_ERROR 159 printk("\n[ERROR] in %s : thread[%x,%x] cannot register kernel vsegs in VMM / cycle %d\n", 160 __FUNCTION__, this->process->pid, this->trdid, cycle ); 161 #endif 175 162 printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ ); 176 163 return -1; … … 233 220 if( error ) 234 221 { 235 printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ ); 222 223 #if DEBUG_PROCESS_ERROR 224 printk("\n[ERROR] in %s : thread[%x,%x] cannot open stdin pseudo file / cycle %d\n", 225 __FUNCTION__, this->process->pid, this->trdid, cycle ); 226 #endif 236 227 return -1; 237 228 } … … 256 247 if( error ) 257 248 { 258 printk("\n[ERROR] in %s : cannot open stdout pseudo-file\n", __FUNCTION__ ); 249 250 #if DEBUG_PROCESS_ERROR 251 printk("\n[ERROR] in %s : thread[%x,%x] cannot open stdout pseudo file / cycle %d\n", 252 __FUNCTION__, this->process->pid, this->trdid, cycle ); 253 #endif 259 254 return -1; 260 255 } … … 279 274 if( error ) 280 275 { 281 printk("\n[ERROR] in %s : cannot open stderr pseudo-file\n", __FUNCTION__ ); 276 277 #if DEBUG_PROCESS_ERROR 278 printk("\n[ERROR] in %s : thread[%x,%x] cannot open stderr pseudo file / cycle %d\n", 279 __FUNCTION__, this->process->pid, this->trdid, cycle ); 280 #endif 282 281 return -1; 283 282 } … … 302 301 303 302 // recreate all open files from parent process fd_array to child process fd_array 304 process_fd_replicate( process_xp , parent_xp ); 303 error = process_fd_replicate( process_xp , parent_xp ); 304 305 if( error ) 306 { 307 308 #if DEBUG_PROCESS_ERROR 309 printk("\n[ERROR] in %s : thread[%x,%x] cannot replicate fd_array / cycle %d\n", 310 __FUNCTION__, this->process->pid, this->trdid, cycle ); 311 #endif 312 return -1; 313 } 314 305 315 } 306 316 … … 379 389 vmm_t * vmm; 380 390 391 #if DEBUG_PROCESS_COPY_INIT || DEBUG_PROCESS_ERROR 392 thread_t * this = CURRENT_THREAD; 393 uint32_t cycle = (uint32_t)hal_get_cycles(); 394 #endif 395 381 396 // get reference process cluster and local pointer 382 397 cxy_t ref_cxy = GET_CXY( reference_process_xp ); … … 394 409 395 410 #if DEBUG_PROCESS_COPY_INIT 396 thread_t * this = CURRENT_THREAD;397 uint32_t cycle = (uint32_t)hal_get_cycles();398 411 if( DEBUG_PROCESS_COPY_INIT < cycle ) 399 412 printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n", … … 410 423 // create an empty GPT as required by the architecture 411 424 error = hal_gpt_create( &vmm->gpt ); 425 412 426 if( error ) 413 427 { 414 printk("\n[ERROR] in %s : cannot create empty GPT\n", __FUNCTION__ ); 428 429 #if DEBUG_PROCESS_ERROR 430 printk("\n[ERROR] in %s : thread[%x,%x] cannot create empty GPT / cycle %d\n", 431 __FUNCTION__, this->process->pid, this->trdid, cycle ); 432 #endif 415 433 return -1; 416 434 } … … 421 439 // register kernel vsegs in VMM as required by the architecture 422 440 error = hal_vmm_kernel_update( local_process ); 441 423 442 if( error ) 424 443 { 425 printk("\n[ERROR] in %s : cannot register kernel vsegs in VMM\n", __FUNCTION__ ); 444 445 #if DEBUG_PROCESS_ERROR 446 printk("\n[ERROR] in %s : thread[%x,%x] cannot register kernel vsegs in VMM / cycle %d\n", 447 __FUNCTION__, this->process->pid, this->trdid, cycle ); 448 #endif 426 449 return -1; 427 450 } … … 431 454 // initialize locks protecting GPT and VSL 432 455 error = vmm_user_init( local_process ); 456 433 457 if( error ) 434 458 { 435 printk("\n[ERROR] in %s : cannot register user vsegs in VMM\n", __FUNCTION__ ); 459 460 #if DEBUG_PROCESS_ERROR 461 printk("\n[ERROR] in %s : thread[%x,%x] cannot register user vsegs in VMM / cycle %d\n", 462 __FUNCTION__, this->process->pid, this->trdid, cycle ); 463 #endif 436 464 return -1; 437 465 } … … 598 626 599 627 // release memory allocated to process descriptor 600 process_free( process);628 kmem_free( process , bits_log2(sizeof(process_t)) ); 601 629 602 630 #if DEBUG_PROCESS_DESTROY … … 974 1002 { 975 1003 error_t error; 976 process_t * process _ptr;// local pointer on process1004 process_t * process; // local pointer on process 977 1005 xptr_t process_xp; // extended pointer on process 978 1006 1007 #if DEBUG_PROCESS_GET_LOCAL_COPY || DEBUG_PROCESS_ERROR 1008 thread_t * this = CURRENT_THREAD; 1009 uint32_t cycle = (uint32_t)hal_get_cycles(); 1010 #endif 1011 979 1012 cluster_t * cluster = LOCAL_CLUSTER; 980 1013 981 1014 #if DEBUG_PROCESS_GET_LOCAL_COPY 982 thread_t * this = CURRENT_THREAD;983 uint32_t cycle = (uint32_t)hal_get_cycles();984 1015 if( DEBUG_PROCESS_GET_LOCAL_COPY < cycle ) 985 1016 printk("\n[%s] thread[%x,%x] enter for process %x in cluster %x / cycle %d\n", … … 996 1027 { 997 1028 process_xp = XLIST_ELEMENT( iter , process_t , local_list ); 998 process _ptr= GET_PTR( process_xp );999 if( process _ptr->pid == pid )1029 process = GET_PTR( process_xp ); 1030 if( process->pid == pid ) 1000 1031 { 1001 1032 found = true; … … 1017 1048 1018 1049 // allocate memory for local process descriptor 1019 process _ptr = process_alloc();1020 1021 if( process _ptr== NULL ) return NULL;1050 process = kmem_alloc( bits_log2(sizeof(process_t)) , AF_ZERO ); 1051 1052 if( process == NULL ) return NULL; 1022 1053 1023 1054 // initialize local process descriptor copy 1024 error = process_copy_init( process_ptr , ref_xp ); 1025 1026 if( error ) return NULL; 1055 error = process_copy_init( process , ref_xp ); 1056 1057 if( error ) 1058 { 1059 1060 #if DEBUG_PROCESS_ERROR 1061 printk("\n[ERROR] in %s : thread[%x,%x] cannot initialize local process copy / cycle %d\n", 1062 __FUNCTION__, this->process->pid, this->trdid, cycle ); 1063 #endif 1064 return NULL; 1065 } 1027 1066 } 1028 1067 … … 1031 1070 if( DEBUG_PROCESS_GET_LOCAL_COPY < cycle ) 1032 1071 printk("\n[%s] thread[%x,%x] exit in cluster %x / process %x / cycle %d\n", 1033 __FUNCTION__, this->process->pid, this->trdid, local_cxy, process _ptr, cycle );1034 #endif 1035 1036 return process _ptr;1072 __FUNCTION__, this->process->pid, this->trdid, local_cxy, process, cycle ); 1073 #endif 1074 1075 return process; 1037 1076 1038 1077 } // end process_get_local_copy() … … 1111 1150 xptr_t max_xp; // extended pointer on max field in fd_array 1112 1151 1152 #if DEBUG_PROCESS_FD_REGISTER 1153 thread_t * this = CURRENT_THREAD; 1154 uint32_t cycle = (uint32_t)hal_get_cycles(); 1155 #endif 1156 1113 1157 // get target process cluster and local pointer 1114 1158 process_t * process_ptr = GET_PTR( process_xp ); … … 1120 1164 1121 1165 #if DEBUG_PROCESS_FD_REGISTER 1122 thread_t * this = CURRENT_THREAD; 1123 uint32_t cycle = (uint32_t)hal_get_cycles(); 1124 pid_t pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) ); 1166 pid_t tgt_pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) ); 1125 1167 if( DEBUG_PROCESS_FD_REGISTER < cycle ) 1126 1168 printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n", 1127 __FUNCTION__, this->process->pid, this->trdid, pid, cycle );1169 __FUNCTION__, this->process->pid, this->trdid, tgt_pid, cycle ); 1128 1170 #endif 1129 1171 … … 1168 1210 if( DEBUG_PROCESS_FD_REGISTER < cycle ) 1169 1211 printk("\n[%s] thread[%x,%x] exit for process %x / fdid %d / cycle %d\n", 1170 __FUNCTION__, this->process->pid, this->trdid, pid, id, cycle );1212 __FUNCTION__, this->process->pid, this->trdid, tgt_pid, id, cycle ); 1171 1213 #endif 1172 1214 … … 1384 1426 } // end process_fd_get_xptr_from_local() 1385 1427 1386 ///////////////////////////////////////// 1387 voidprocess_fd_replicate( xptr_t dst_xp,1388 xptr_t src_xp )1428 //////////////////////////////////////////// 1429 error_t process_fd_replicate( xptr_t dst_xp, 1430 xptr_t src_xp ) 1389 1431 { 1390 1432 uint32_t fdid; // current file descriptor index … … 1435 1477 if( error ) 1436 1478 { 1437 printk("\n[ERROR] in %s : cannot create new file\n", __FUNCTION__ ); 1438 return; 1479 1480 #if DEBUG_PROCESS_ERROR 1481 thread_t * this = CURRENT_THREAD; 1482 uint32_t cycle = (uint32_t)hal_get_cycles(); 1483 printk("\n[ERROR] in %s : thread[%x,%x] cannot create file descriptor / cycle %d\n", 1484 __FUNCTION__, this->process->pid, this->trdid, cycle ); 1485 #endif 1486 return -1; 1439 1487 } 1440 1488 … … 1446 1494 // release lock on source process fd_array 1447 1495 remote_queuelock_release( src_lock_xp ); 1496 1497 return 0; 1448 1498 1449 1499 } // end process_fd_replicate() … … 1494 1544 uint32_t max = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->fd_array.max )); 1495 1545 1496 printk("\n***** fd_array for pid %x in cluster %x / max %d *****\n", 1546 // get pointers on TXT0 chdev 1547 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 1548 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 1549 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 1550 1551 // get extended pointer on remote TXT0 lock 1552 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 1553 1554 // get TXT0 lock 1555 remote_busylock_acquire( lock_xp ); 1556 1557 nolock_printk("\n***** fd_array for pid %x in cluster %x / max %d *****\n", 1497 1558 pid, process_cxy, max ); 1498 1559 … … 1520 1581 1521 1582 // display relevant file descriptor info 1522 printk(" - %d : type %s / ptr %x (%s)\n",1583 nolock_printk(" - %d : type %s / ptr %x (%s)\n", 1523 1584 fdid, process_fd_type_str(file_type), file_ptr, name ); 1524 1585 } … … 1526 1587 { 1527 1588 // display relevant file decriptor info 1528 printk(" - %d : type %s / ptr %x\n",1589 nolock_printk(" - %d : type %s / ptr %x\n", 1529 1590 fdid , process_fd_type_str(file_type), file_ptr ); 1530 1591 } … … 1532 1593 else 1533 1594 { 1534 printk(" - %d : empty slot\n", 1535 fdid ); 1595 nolock_printk(" - %d : empty slot\n", fdid ); 1536 1596 } 1537 1597 } 1598 1599 // get TXT0 lock 1600 remote_busylock_acquire( lock_xp ); 1601 1538 1602 } // end process_fd_display() 1539 1603 … … 1548 1612 { 1549 1613 ltid_t ltid; 1614 ltid_t ltid_min; 1615 1550 1616 bool_t found = false; 1617 lpid_t lpid = LPID_FROM_PID( process->pid ); 1551 1618 1552 1619 // check arguments … … 1554 1621 assert( __FUNCTION__, (thread != NULL) , "thread argument is NULL" ); 1555 1622 1556 // get the lock protecting th_tbl for all threads 1557 // but the idle thread executing kernel_init (cannot yield) 1623 // get the lock protecting th_tbl for all threads but the idle thread 1558 1624 if( thread->type != THREAD_IDLE ) rwlock_wr_acquire( &process->th_lock ); 1559 1625 1626 // compute ltid_min : 0 for an user thread / 1 for a kernel thread 1627 ltid_min = (lpid == 0) ? 1 : 0; 1628 1560 1629 // scan th_tbl 1561 for( ltid = 0; ltid < CONFIG_THREADS_MAX_PER_CLUSTER ; ltid++ )1630 for( ltid = ltid_min ; ltid < CONFIG_THREADS_MAX_PER_CLUSTER ; ltid++ ) 1562 1631 { 1563 1632 if( process->th_tbl[ltid] == NULL ) … … 1581 1650 if( thread->type != THREAD_IDLE ) rwlock_wr_release( &process->th_lock ); 1582 1651 1583 return (found) ? 0 : 0xFFFFFFFF;1652 return (found) ? 0 : -1; 1584 1653 1585 1654 } // end process_register_thread() … … 1647 1716 "parent process must be the reference process" ); 1648 1717 1649 #if DEBUG_PROCESS_MAKE_FORK 1650 uint32_t cycle ;1718 #if DEBUG_PROCESS_MAKE_FORK || DEBUG_PROCESS_ERROR 1719 uint32_t cycle = (uint32_t)hal_get_cycles(); 1651 1720 thread_t * this = CURRENT_THREAD; 1652 1721 trdid_t trdid = this->trdid; … … 1655 1724 1656 1725 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1657 cycle = (uint32_t)hal_get_cycles();1658 1726 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1659 1727 printk("\n[%s] thread[%x,%x] enter / cluster %x / cycle %d\n", … … 1662 1730 1663 1731 // allocate a process descriptor 1664 process = process_alloc();1732 process = kmem_alloc( bits_log2(sizeof(process_t)) , AF_ZERO ); 1665 1733 1666 1734 if( process == NULL ) 1667 1735 { 1668 printk("\n[ERROR] in %s : cannot get process in cluster %x\n", 1669 __FUNCTION__, local_cxy ); 1736 1737 #if DEBUG_PROCESS_ERROR 1738 printk("\n[ERROR] in %s : thread[%x,%x] cannot allocate process descriptor / cxy %x / cycle %d\n", 1739 __FUNCTION__, pid, trdid, local_cxy, cycle ); 1740 #endif 1670 1741 return -1; 1671 1742 } … … 1675 1746 if( error ) 1676 1747 { 1677 printk("\n[ERROR] in %s : cannot get PID in cluster %x\n", 1678 __FUNCTION__, local_cxy ); 1679 process_free( process ); 1748 1749 #if DEBUG_PROCESS_ERROR 1750 printk("\n[ERROR] in %s : thread[%x,%x] cannot get PID / cxy %x / cycle %d\n", 1751 __FUNCTION__, pid, trdid, local_cxy, cycle ); 1752 #endif 1753 kmem_free( process , bits_log2(sizeof(process_t)) ); 1680 1754 return -1; 1681 1755 } 1682 1756 1683 1757 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1684 cycle = (uint32_t)hal_get_cycles();1685 1758 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1686 printk("\n[%s] thread[%x,%x] allocated child_process %x / cycle %d\n",1687 __FUNCTION__, pid, trdid, new_pid , cycle);1759 printk("\n[%s] thread[%x,%x] allocated child_process %x\n", 1760 __FUNCTION__, pid, trdid, new_pid ); 1688 1761 #endif 1689 1762 … … 1694 1767 if( error ) 1695 1768 { 1696 printk("\n[ERROR] in %s : cannot initialize child process in cluster %x\n", 1697 __FUNCTION__, local_cxy ); 1698 process_free( process ); 1769 1770 #if DEBUG_PROCESS_ERROR 1771 printk("\n[ERROR] in %s : thread[%x,%x] cannot initialize child process / cxy %x / cycle %d\n", 1772 __FUNCTION__, pid, trdid, local_cxy, cycle ); 1773 #endif 1774 cluster_pid_release( new_pid ); 1775 kmem_free( process , bits_log2(sizeof(process_t)) ); 1699 1776 return -1; 1700 1777 } 1701 1778 1702 1779 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1703 cycle = (uint32_t)hal_get_cycles();1704 1780 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1705 printk("\n[%s] thread[%x,%x] initialized child_process %x / cycle %d\n",1706 __FUNCTION__, pid, trdid, new_pid , cycle);1781 printk("\n[%s] thread[%x,%x] initialized child_process %x\n", 1782 __FUNCTION__, pid, trdid, new_pid ); 1707 1783 #endif 1708 1784 … … 1712 1788 if( error ) 1713 1789 { 1714 printk("\n[ERROR] in %s : cannot copy VMM in cluster %x\n", 1715 __FUNCTION__, local_cxy ); 1716 process_free( process ); 1790 1791 #if DEBUG_PROCESS_ERROR 1792 printk("\n[ERROR] in %s : thread[%x,%x] cannot copy VMM to child process / cxy %x / cycle %d\n", 1793 __FUNCTION__, pid, trdid, local_cxy, cycle ); 1794 #endif 1717 1795 cluster_pid_release( new_pid ); 1796 kmem_free( process , bits_log2(sizeof(process_t)) ); 1718 1797 return -1; 1719 1798 } 1720 1799 1721 1800 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1722 cycle = (uint32_t)hal_get_cycles();1723 1801 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1724 1802 { 1725 printk("\n[%s] thread[%x,%x] copied VMM from parent to child / cycle %d\n",1726 __FUNCTION__, pid, trdid , cycle);1803 printk("\n[%s] thread[%x,%x] copied VMM from parent to child\n", 1804 __FUNCTION__, pid, trdid ); 1727 1805 hal_vmm_display( XPTR( local_cxy , process ) , true ); 1728 1806 } … … 1736 1814 1737 1815 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1738 cycle = (uint32_t)hal_get_cycles();1739 1816 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1740 printk("\n[%s] thread[%x,%x] / child_process %x takes TXT ownership / cycle %d\n",1741 __FUNCTION__ , pid, trdid, new_pid , cycle);1817 printk("\n[%s] thread[%x,%x] / child_process %x takes TXT ownership\n", 1818 __FUNCTION__ , pid, trdid, new_pid ); 1742 1819 #endif 1743 1820 … … 1753 1830 if( error ) 1754 1831 { 1755 printk("\n[ERROR] in %s : cannot create thread in cluster %x\n", 1756 __FUNCTION__, local_cxy ); 1757 process_free( process ); 1832 1833 #if DEBUG_PROCESS_ERROR 1834 printk("\n[ERROR] in %s : thread[%x,%x] cannot create main thread / cxy %x / cycle %d\n", 1835 __FUNCTION__, pid, trdid, local_cxy, cycle ); 1836 #endif 1758 1837 cluster_pid_release( new_pid ); 1838 kmem_free( process , bits_log2(sizeof(process_t)) ); 1759 1839 return -1; 1760 1840 } … … 1765 1845 1766 1846 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1767 cycle = (uint32_t)hal_get_cycles();1768 1847 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1769 printk("\n[%s] thread[%x,%x] created main thread %x / cycle %d\n",1770 __FUNCTION__, pid, trdid, thread , cycle);1848 printk("\n[%s] thread[%x,%x] created main thread %x\n", 1849 __FUNCTION__, pid, trdid, thread ); 1771 1850 #endif 1772 1851 … … 1787 1866 1788 1867 #if( DEBUG_PROCESS_MAKE_FORK & 1 ) 1789 cycle = (uint32_t)hal_get_cycles();1790 1868 if( DEBUG_PROCESS_MAKE_FORK < cycle ) 1791 printk("\n[%s] thread[%x,%x] set COW in DATA / ANON / REMOTE for parent and child / cycle %d\n",1792 __FUNCTION__, pid, trdid , cycle);1869 printk("\n[%s] thread[%x,%x] set COW in DATA / ANON / REMOTE for parent and child\n", 1870 __FUNCTION__, pid, trdid ); 1793 1871 #endif 1794 1872 … … 1819 1897 } // end process_make_fork() 1820 1898 1821 ////////////////////////////////////////////////i////////////////////////////////////// 1822 // This static function is called by the thread_user_exec() function : 1823 // - to register the main() arguments (args) in the <exec_info> structure. 1824 // - to register the environment variables (envs) in the <exec_info> structure. 1825 // In both cases the input is an array of NULL terminated string pointers in user 1826 // space, and the strings can be dispatched anywhere in the user process space. 1827 // This array of pointers is defined by the <u_pointers> argument. The empty slots 1828 // contain the NULL value, and the N non-empty slots are indexed from 0 to (N-1). 1829 // - The max number of envs, and the max number of args are defined by the 1830 // CONFIG_PROCESS_ARGS_NR and CONFIG_PROCESS_ENVS_MAX_NR parameters. 1831 // - The numbers of pages to store the (args) and (envs) strings are defined by the 1832 // CONFIG_VMM_ENVS_SIZE and CONFIG_VMM_STACK_SIZE parameters. 1833 /////////////////////////////////////////////////////////////////////////////////////// 1834 // Implementation note: 1835 // It allocates a kernel buffer to store a kernel copy of both the array of pointers, 1836 // and the strings. It set the pointers and copies the strings in this kernel buffer. 1837 // Finally, it registers the buffer & the actual number of strings in the process 1838 // exec_info structure (defined in the <process.h> file). 1839 /////////////////////////////////////////////////////////////////////////////////////// 1840 // @ is_args : [in] true if called for (args) / false if called for (envs). 1841 // @ u_pointers : [in] array of pointers on the strings (in user space). 1842 // @ exec_info : [out] pointer on the exec_info structure. 1843 // @ return 0 if success / non-zero if too many strings or no memory. 1844 /////////////////////////////////////////////////////////////////////////////////////// 1845 error_t process_exec_get_strings( bool_t is_args, 1846 char ** u_pointers, 1847 exec_info_t * exec_info ) 1848 { 1849 uint32_t index; // slot index in pointers array 1850 uint32_t length; // string length (in bytes) 1851 uint32_t pointers_bytes; // number of bytes to store pointers 1852 uint32_t max_index; // max size of pointers array 1853 char ** k_pointers; // base of kernel array of pointers 1854 char * k_buf_ptr; // pointer on first empty slot in strings buffer 1855 uint32_t k_buf_space; // number of bytes available in string buffer 1856 kmem_req_t req; // kernel memory allocator request 1857 char * k_buf; // kernel buffer for both pointers & strings 1858 1859 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1860 thread_t * this = CURRENT_THREAD; 1861 uint32_t cycle = (uint32_t)hal_get_cycles(); 1862 #endif 1863 1864 // Allocate one block of physical memory for both the pointers and the strings 1865 // as defined by the CONFIG_VMM_ARGS_SIZE and CONFIG_VMM_ENVS_SIZE parameters 1866 // - the array of pointers is stored in the first bytes of the kernel buffer 1867 // - the strings themselve are stored in the next bytes of this buffer 1868 // Set the k_pointers, k_buf_ptr, k_buf_space, and max_index 1869 1870 if( is_args ) 1871 { 1872 req.type = KMEM_PPM; 1873 req.order = bits_log2( CONFIG_VMM_ARGS_SIZE ); 1874 req.flags = AF_KERNEL | AF_ZERO; 1875 k_buf = kmem_alloc( &req ); 1876 1877 pointers_bytes = CONFIG_PROCESS_ARGS_MAX_NR * sizeof(char *); 1878 k_pointers = (char **)k_buf; 1879 k_buf_ptr = k_buf + pointers_bytes; 1880 k_buf_space = (CONFIG_VMM_ARGS_SIZE * CONFIG_PPM_PAGE_SIZE) - pointers_bytes; 1881 max_index = CONFIG_PROCESS_ARGS_MAX_NR; 1882 1883 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1884 if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle ) 1885 printk("\n[%s] thread[%x,%x] for args / u_buf %x / k_buf %x\n", 1886 __FUNCTION__, this->process->pid, this->trdid, u_pointers, k_buf ); 1887 #endif 1888 1889 } 1890 else 1891 { 1892 req.type = KMEM_PPM; 1893 req.order = bits_log2( CONFIG_VMM_ENVS_SIZE ); 1894 req.flags = AF_KERNEL | AF_ZERO; 1895 k_buf = kmem_alloc( &req ); 1896 1897 pointers_bytes = CONFIG_PROCESS_ENVS_MAX_NR * sizeof(char *); 1898 k_pointers = (char **)k_buf; 1899 k_buf_ptr = k_buf + pointers_bytes; 1900 k_buf_space = (CONFIG_VMM_ENVS_SIZE * CONFIG_PPM_PAGE_SIZE) - pointers_bytes; 1901 max_index = CONFIG_PROCESS_ENVS_MAX_NR; 1902 1903 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1904 if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle ) 1905 printk("\n[%s] thread[%x,%x] for envs / u_buf %x / k_buf %x\n", 1906 __FUNCTION__, this->process->pid, this->trdid, u_pointers, k_buf ); 1907 #endif 1908 1909 } 1910 1911 // copy the user array of pointers to kernel buffer 1912 hal_copy_from_uspace( XPTR( local_cxy , k_pointers ), 1913 u_pointers, 1914 pointers_bytes ); 1915 1916 // WARNING : the pointers copied in the k_pointers[] array are user pointers, 1917 // after the loop below, the k_pointers[] array contains kernel pointers. 1918 1919 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1920 if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle ) 1921 printk("\n[%s] thread[%x,%x] copied u_ptr array to k_ptr array\n" 1922 " p0 = %x / p1 = %x / p2 = %x / p3 = %x\n", 1923 __FUNCTION__, this->process->pid, this->trdid, 1924 k_pointers[0], k_pointers[1], k_pointers[2], k_pointers[3] ); 1925 #endif 1926 1927 // scan kernel array of pointers to copy strings to kernel buffer 1928 for( index = 0 ; index < max_index ; index++ ) 1929 { 1930 // exit loop if (k_pointers[] == NUll) 1931 if( k_pointers[index] == NULL ) break; 1932 1933 // compute string length 1934 length = hal_strlen_from_uspace( k_pointers[index] ) + 1; 1935 1936 // return error if overflow in kernel buffer 1937 if( length > k_buf_space ) return -1; 1938 1939 // copy the string to kernel buffer 1940 hal_copy_from_uspace( XPTR( local_cxy , k_buf_ptr ), 1941 k_pointers[index], 1942 length ); 1943 1944 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1945 if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle ) 1946 printk("\n[%s] thread[%x,%x] copied string[%d] <%s> to kernel buffer / length %d\n", 1947 __FUNCTION__, this->process->pid, this->trdid, index, k_buf_ptr, length ); 1948 #endif 1949 1950 // replace the user pointer by a kernel pointer in the k_pointer[] array 1951 k_pointers[index] = k_buf_ptr; 1952 1953 // increment loop variables 1954 k_buf_ptr += length; 1955 k_buf_space -= length; 1956 1957 } // end loop on index 1958 1959 // update into exec_info structure 1960 if( is_args ) 1961 { 1962 exec_info->args_pointers = k_pointers; 1963 exec_info->args_nr = index; 1964 } 1965 else 1966 { 1967 exec_info->envs_pointers = k_pointers; 1968 exec_info->envs_buf_free = k_buf_ptr; 1969 exec_info->envs_nr = index; 1970 } 1971 1972 #if DEBUG_PROCESS_EXEC_GET_STRINGS 1973 if( DEBUG_PROCESS_EXEC_GET_STRINGS < cycle ) 1974 printk("\n[%s] thread[%x,%x] copied %d strings to kernel buffer\n", 1975 __FUNCTION__, this->process->pid, this->trdid, index ); 1976 #endif 1977 1978 return 0; 1979 1980 } // end process_exec_get_strings() 1899 #if DEBUG_PROCESS_MAKE_EXEC 1900 1901 ///////////////////////////////////////////////////////////////////////////////////////// 1902 // This static debug function displays the current state of the exec_info structure 1903 // embedded in the calling process descriptor. 1904 // 1905 // WARNING : It can be used after execution of the sys_exec function, but it cannot 1906 // be used after execution of the process_make_exec() function, because the 1907 // kernel pointers have been replaced by user pointers. 1908 ///////////////////////////////////////////////////////////////////////////////////////// 1909 static void process_exec_info_display( bool_t args_ok, 1910 bool_t envs_ok ) 1911 { 1912 uint32_t i; 1913 char * str; // local pointer on a string 1914 1915 process_t * process = CURRENT_THREAD->process; 1916 1917 // get relevant info from calling process descriptor 1918 pid_t pid = process->pid; 1919 1920 uint32_t args_nr = process->exec_info.args_nr; 1921 char ** args = process->exec_info.args_pointers; 1922 1923 uint32_t envs_nr = process->exec_info.envs_nr; 1924 char ** envs = process->exec_info.envs_pointers; 1925 1926 char * path = process->exec_info.path; 1927 1928 // get pointers on TXT0 chdev 1929 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 1930 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 1931 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 1932 1933 // get extended pointer on remote TXT0 lock 1934 xptr_t lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 1935 1936 // get TXT0 lock 1937 remote_busylock_acquire( lock_xp ); 1938 1939 nolock_printk("\n***** exec_info for process %x in cluster %x / %s\n", 1940 pid , local_cxy , path ); 1941 1942 // display arguments if required 1943 if( args_ok ) 1944 { 1945 for( i = 0 ; i < args_nr ; i++ ) 1946 { 1947 str = args[i]; 1948 if( str != NULL) // display pointer and string 1949 nolock_printk(" - &arg[%d] = %x / arg[%d] = <%s>\n", i, str, i, str ); 1950 else // display WARNING 1951 nolock_printk(" - unexpected NULL pointer for &arg[%d]\n", i ); 1952 } 1953 } 1954 1955 // display env variables if required 1956 if( envs_ok ) 1957 { 1958 for( i = 0 ; i < envs_nr ; i++ ) 1959 { 1960 str = envs[i]; 1961 if( str != NULL) // display pointer and string 1962 nolock_printk(" - &env[%d] = %x / env[%d] = <%s>\n", i, str, i, str ); 1963 else // display WARNING 1964 nolock_printk(" - unexpected NULL pointer for &env[%d]\n", i ); 1965 } 1966 } 1967 1968 // release TXT0 lock 1969 remote_busylock_release( lock_xp ); 1970 1971 } // end process_exec_info_display() 1972 1973 #endif // DEBUG_PROCESS_MAKE_EXEC 1981 1974 1982 1975 ///////////////////////////////// … … 2003 1996 uint32_t envs_size; // envs vseg size (bytes) 2004 1997 1998 #if DEBUG_PROCESS_MAKE_EXEC || DEBUG_PROCESS_ERROR 1999 uint32_t cycle = (uint32_t)hal_get_cycles(); 2000 #endif 2001 2005 2002 // get calling thread, process, pid, trdid, and ref_xp 2006 2003 this = CURRENT_THREAD; … … 2014 2011 2015 2012 #if DEBUG_PROCESS_MAKE_EXEC 2016 uint32_t cycle = (uint32_t)hal_get_cycles();2017 2013 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 2018 2014 printk("\n[%s] thread[%x,%x] enters for <%s> / cycle %d\n", … … 2032 2028 if( error ) 2033 2029 { 2034 printk("\n[ERROR] in %s : thread[%x,%x] failed to open file <%s>\n", 2035 __FUNCTION__, pid, trdid, elf_path ); 2030 2031 #if DEBUG_PROCESS_ERROR 2032 printk("\n[ERROR] in %s : thread[%x,%x] failed to open file <%s> / cycle %d\n", 2033 __FUNCTION__, pid, trdid, elf_path, cycle ); 2034 #endif 2036 2035 return -1; 2037 2036 } … … 2064 2063 #endif 2065 2064 2066 // 4. register the "args" vseg in VSL and map it in GPT, if required 2067 // this vseg contains both the array of pointers and the strings 2065 // 4. register the "args" vseg in VSL and map it in GPT, if args_nr != 0. 2066 // As this vseg contains an array of pointers, the kernel pointers 2067 // are replaced by user pointers in new process space. 2068 2068 args_nr = process->exec_info.args_nr; 2069 2069 … … 2071 2071 { 2072 2072 // get args vseg base and size in user space 2073 args_base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_ SHIFT;2074 args_size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_ SHIFT;2073 args_base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_ORDER; 2074 args_size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_ORDER; 2075 2075 2076 2076 // create and register args vseg in VMM … … 2085 2085 if( vseg == NULL ) 2086 2086 { 2087 printk("\n[ERROR] in %s : thread[%x,%x] cannot get args vseg for <%s>\n", 2088 __FUNCTION__, pid, trdid, elf_path ); 2087 2088 #if DEBUG_PROCESS_ERROR 2089 printk("\n[ERROR] in %s : thread[%x,%x] cannot create args vseg for <%s> / cycle %d\n", 2090 __FUNCTION__, pid, trdid, elf_path, cycle ); 2091 #endif 2089 2092 return -1; 2090 2093 } … … 2098 2101 } 2099 2102 #endif 2100 // map all pages for th is"args" vseg2103 // map all pages for the "args" vseg 2101 2104 uint32_t fake_attr; // required for hal_gpt_lock_pte() 2102 2105 ppn_t fake_ppn; // required for hal_gpt_lock_pte() 2103 2106 2104 xptr_t gpt = XPTR( local_cxy , &process->vmm.gpt ); 2105 uint32_t attr = GPT_MAPPED | GPT_SMALL | GPT_READABLE | GPT_USER | GPT_CACHABLE; 2106 vpn_t vpn = CONFIG_VMM_UTILS_BASE; 2107 ppn_t ppn = ((ppn_t)process->exec_info.args_pointers >> CONFIG_PPM_PAGE_SHIFT); 2107 xptr_t base_xp = XPTR( local_cxy , process->exec_info.args_pointers ); 2108 xptr_t gpt_xp = XPTR( local_cxy , &process->vmm.gpt ); 2109 uint32_t attr = GPT_MAPPED | GPT_SMALL | GPT_READABLE | GPT_USER | GPT_CACHABLE; 2110 vpn_t vpn = CONFIG_VMM_UTILS_BASE; 2111 ppn_t ppn = ppm_base2ppn( base_xp ); 2108 2112 2109 2113 for( n = 0 ; n < CONFIG_VMM_ARGS_SIZE ; n++ ) 2110 2114 { 2111 2115 // lock the PTE 2112 if (hal_gpt_lock_pte( gpt , vpn , &fake_attr , &fake_ppn ) )2116 if (hal_gpt_lock_pte( gpt_xp , vpn + n , &fake_attr , &fake_ppn ) ) 2113 2117 { 2114 printk("\n[ERROR] in %s : thread[%x,%x] cannot map args vpn %x for <%s>\n", 2115 __FUNCTION__, pid, trdid, vpn, elf_path ); 2118 2119 #if DEBUG_PROCESS_ERROR 2120 printk("\n[ERROR] in %s : thread[%x,%x] cannot map vpn[%x] of args vseg for <%s> / cycle %d\n", 2121 __FUNCTION__, pid, trdid, vpn + n , elf_path , cycle ); 2122 #endif 2116 2123 return -1; 2117 2124 } 2118 2125 2119 2126 // map and unlock the PTE 2120 hal_gpt_set_pte( gpt , vpn + n , attr , ppn + n );2121 2127 hal_gpt_set_pte( gpt_xp , vpn + n , attr , ppn + n ); 2128 } 2122 2129 2123 2130 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) … … 2127 2134 __FUNCTION__, pid, trdid ); 2128 2135 hal_vmm_display( ref_xp , true ); 2136 process_exec_info_display( true , false ); // args & not envs 2129 2137 } 2130 2138 #endif 2131 2139 2132 // set user space pointers in array of pointers 2133 char ** ptr = process->exec_info.args_pointers; 2134 2140 // build pointer on args buffer in kernel space 2141 char ** k_args = process->exec_info.args_pointers; 2142 2143 // build pointer on args buffer in user space 2144 char ** u_args = (char **)args_base; 2145 2146 // set user space pointers in kernel args buffer 2135 2147 for( n = 0 ; n < args_nr ; n++ ) 2136 2148 { 2137 ptr[n] = ptr[n] + args_base - (intptr_t)ptr;2149 k_args[n] = (char *)((intptr_t)k_args[n] + (intptr_t)u_args - (intptr_t)k_args); 2138 2150 } 2139 } 2140 2141 // 5. register the "envs" vseg in VSL and map it in GPT, if required 2142 // this vseg contains both the array of pointers and the strings 2151 2152 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 2153 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 2154 printk("\n[%s] thread[%x,%x] args user pointers set in exec_info\n", 2155 __FUNCTION__, pid, trdid ); 2156 #endif 2157 2158 } 2159 2160 // 5. register the "envs" vseg in VSL and map it in GPT, if envs_nr != 0. 2161 // As this vseg contains an array of pointers, the kernel pointers 2162 // are replaced by user pointers in new process space. 2163 2143 2164 envs_nr = process->exec_info.envs_nr; 2144 2165 … … 2146 2167 { 2147 2168 // get envs vseg base and size in user space from config 2148 envs_base = (CONFIG_VMM_UTILS_BASE + CONFIG_VMM_ARGS_SIZE) << CONFIG_PPM_PAGE_SHIFT; 2149 envs_size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT; 2150 2151 // TODO (inspired from args) 2169 envs_base = (CONFIG_VMM_UTILS_BASE + CONFIG_VMM_ARGS_SIZE) << CONFIG_PPM_PAGE_ORDER; 2170 envs_size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_ORDER; 2171 2172 // TODO (should be similar to the code for args above) 2173 2174 #if( DEBUG_PROCESS_MAKE_EXEC & 1 ) 2175 if( DEBUG_PROCESS_MAKE_EXEC < cycle ) 2176 printk("\n[%s] thread[%x,%x] envs user pointers set in exec_info\n", 2177 __FUNCTION__, pid, trdid ); 2178 #endif 2179 2152 2180 } 2153 2181 … … 2156 2184 // register extended pointer on .elf file in process descriptor 2157 2185 error = elf_load_process( file_xp , process ); 2186 2158 2187 if( error ) 2159 2188 { 2160 printk("\n[ERROR] in %s : thread[%x,%x] failed to access <%s>\n", 2161 __FUNCTION__, pid, trdid, elf_path ); 2189 2190 #if DEBUG_PROCESS_ERROR 2191 printk("\n[ERROR] in %s : thread[%x,%x] failed to access file <%s> / cycle %d\n", 2192 __FUNCTION__, pid, trdid , elf_path , cycle ); 2193 #endif 2162 2194 return -1; 2163 2195 } … … 2183 2215 if( vseg == NULL ) 2184 2216 { 2185 printk("\n[ERROR] in %s : thread[%x,%x] cannot set u_stack vseg for <%s>\n", 2186 __FUNCTION__, pid, trdid, elf_path ); 2217 2218 #if DEBUG_PROCESS_ERROR 2219 printk("\n[ERROR] in %s : thread[%x,%x] failed to set u_stack vseg for <%s> / cycle %d\n", 2220 __FUNCTION__, pid, trdid , elf_path , cycle ); 2221 #endif 2187 2222 return -1; 2188 2223 } … … 2205 2240 if( error ) 2206 2241 { 2207 printk("\n[ERROR] in %s : thread[%x,%x] cannot update thread for <%s>\n", 2208 __FUNCTION__ , pid, trdid, elf_path ); 2242 2243 #if DEBUG_PROCESS_ERROR 2244 printk("\n[ERROR] in %s : thread[%x,%x] failed to set main thread for <%s> / cycle %d\n", 2245 __FUNCTION__, pid, trdid , elf_path , cycle ); 2246 #endif 2209 2247 return -1; 2210 2248 } 2211 2249 2250 // should not be reached, avoid a warning 2212 2251 return 0; 2213 2252 … … 2294 2333 if( DEBUG_PROCESS_ZERO_CREATE < cycle ) 2295 2334 printk("\n[%s] initialized hal specific VMM in cluster%x\n", __FUNCTION__, local_cxy ); 2335 hal_vmm_display( XPTR( local_cxy , process ) , true ); 2296 2336 #endif 2297 2337 … … 2356 2396 2357 2397 // allocates memory for process descriptor from local cluster 2358 process = process_alloc(); 2398 process = kmem_alloc( bits_log2(sizeof(process_t)) , AF_ZERO ); 2359 2399 if( process == NULL ) 2360 2400 { … … 2506 2546 } // end process_init_create() 2507 2547 2508 ///////////////////////////////////////// 2509 void process_display( xptr_t process_xp ) 2510 { 2511 process_t * process_ptr; 2512 cxy_t process_cxy; 2548 /////////////////////////////////////////////////// 2549 uint32_t process_build_string( xptr_t process_xp, 2550 char * buffer, 2551 uint32_t size ) 2552 { 2553 int32_t length; // actual length of the string 2554 2555 process_t * process_ptr; // process descriptor local pointer 2556 cxy_t process_cxy; // process descriptor cluster identifier 2513 2557 2514 2558 xptr_t parent_xp; // extended pointer on parent process 2515 process_t * parent_ptr; 2516 cxy_t parent_cxy; 2559 process_t * parent_ptr; // parent process local pointer 2560 cxy_t parent_cxy; // parent process cluster identifier 2517 2561 2518 2562 xptr_t owner_xp; // extended pointer on owner process 2519 process_t * owner_ptr; 2520 cxy_t owner_cxy; 2521 2522 pid_t pid; 2523 pid_t ppid; 2524 lpid_t lpid; 2525 uint32_t state; 2526 uint32_t th_nr; 2563 process_t * owner_ptr; // owner process local pointer 2564 cxy_t owner_cxy; // owner process cluster identifier 2565 2566 pid_t pid; // process identifier 2567 pid_t ppid; // parent process identifier 2568 lpid_t lpid; // local process identifier 2569 uint32_t state; // terminaison state 2570 uint32_t th_nr; // number of threads 2527 2571 2528 2572 xptr_t txt_file_xp; // extended pointer on TXT_RX file descriptor … … 2540 2584 char elf_name[CONFIG_VFS_MAX_NAME_LENGTH]; 2541 2585 2586 assert( __FUNCTION__ , (size >= 80 ) , "buffer size too small" ); 2587 2542 2588 // get cluster and local pointer on process 2543 2589 process_ptr = GET_PTR( process_xp ); … … 2566 2612 if( lpid ) // user process 2567 2613 { 2568 2569 2614 // get extended pointer on file descriptor associated to TXT_RX 2570 2615 txt_file_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->fd_array.array[0] ) ); 2571 2616 2572 2573 2617 assert( __FUNCTION__, (txt_file_xp != XPTR_NULL) , 2618 "process must be attached to one TXT terminal" ); 2574 2619 2575 2620 // get TXT_RX chdev pointers … … 2582 2627 XPTR( txt_chdev_cxy , txt_chdev_ptr->name ) ); 2583 2628 2629 // get TXT_owner process 2584 2630 txt_owner_xp = (xptr_t)hal_remote_l64( XPTR( txt_chdev_cxy, 2585 2631 &txt_chdev_ptr->ext.txt.owner_xp ) ); 2586 2587 2632 // get process .elf name 2588 2633 elf_file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->vfs_bin_xp ) ); … … 2594 2639 else // kernel process_zero 2595 2640 { 2596 // TXT name and .elf name are not registered in kernel process _zero2641 // TXT name and .elf name are not registered in kernel process 2597 2642 strcpy( txt_name , "txt0_rx" ); 2598 2643 txt_owner_xp = process_xp; … … 2603 2648 if( txt_owner_xp == process_xp ) 2604 2649 { 2605 nolock_printk("PID %X | %s (FG) | %X | PPID %X | TS %X | %d | %s\n", 2650 length = snprintk( buffer, size, 2651 "PID %X | %s (FG) | %X | PPID %X | TS %X | %d | %s\n", 2606 2652 pid, txt_name, process_ptr, ppid, state, th_nr, elf_name ); 2607 2653 } 2608 2654 else 2609 2655 { 2610 nolock_printk("PID %X | %s (BG) | %X | PPID %X | TS %X | %d | %s\n", 2656 length = snprintk( buffer, size, 2657 "PID %X | %s (BG) | %X | PPID %X | TS %X | %d | %s\n", 2611 2658 pid, txt_name, process_ptr, ppid, state, th_nr, elf_name ); 2612 2659 } 2660 2661 // check length 2662 if( (length < 0) ) 2663 { 2664 length = snprintk( buffer , size , 2665 "buffer too small for process %x in cluster %x", pid , process_cxy ); 2666 } 2667 2668 return length; 2669 2670 } // end process_build_string() 2671 2672 ///////////////////////////////////////// 2673 void process_display( xptr_t process_xp ) 2674 { 2675 char buffer[CONFIG_PROCESS_DISPLAY_BUF_SIZE]; 2676 2677 // build the string to be displayed 2678 process_build_string( process_xp, 2679 buffer, 2680 CONFIG_PROCESS_DISPLAY_BUF_SIZE ); 2681 // display the string 2682 nolock_puts( buffer ); 2683 2613 2684 } // end process_display() 2614 2685
Note: See TracChangeset
for help on using the changeset viewer.