Changeset 15031

Show
Ignore:
Timestamp:
07/02/08 06:14:19 (6 months ago)
Author:
hayamiz
Message:

lang/cplusplus/minipy/trunk: マルチスレッド,mutex,cond var実装完了.サンプルとしてhttpサーバーも実装

Location:
lang/cplusplus/minipy/trunk
Files:
3 added
8 modified

Legend:

Unmodified
Added
Removed
  • lang/cplusplus/minipy/trunk/bootstrap.inc

    r14995 r15031  
    11/* !! DO NOT EDIT THIS FILE !! */ 
    2 /* this file was generated by etc/gen_bootstrap.rb @ Tue Jul 01 17:13:28 +0900 2008 */ 
     2/* this file was generated by etc/gen_bootstrap.rb @ Wed Jul 02 05:40:47 +0900 2008 */ 
    33genv.set_sym(Symbol::get("is_int"), Py_val::mk_nfun(Symbol::get("is_int"), 1, native::is_int)); 
    44genv.set_sym(Symbol::get("is_float"), Py_val::mk_nfun(Symbol::get("is_float"), 1, native::is_float)); 
     
    9292genv.set_sym(Symbol::get("ntv_random"), Py_val::mk_nfun(Symbol::get("ntv_random"), -1, native::ntv_random)); 
    9393genv.set_sym(Symbol::get("sys_sleep"), Py_val::mk_nfun(Symbol::get("sys_sleep"), 1, native::sys_sleep)); 
     94genv.set_sym(Symbol::get("mutex"), Py_val::mk_nfun(Symbol::get("mutex"), 0, native::mutex)); 
     95genv.set_sym(Symbol::get("lock"), Py_val::mk_nfun(Symbol::get("lock"), 1, native::lock)); 
     96genv.set_sym(Symbol::get("unlock"), Py_val::mk_nfun(Symbol::get("unlock"), 1, native::unlock)); 
     97genv.set_sym(Symbol::get("condition"), Py_val::mk_nfun(Symbol::get("condition"), 1, native::condition)); 
     98genv.set_sym(Symbol::get("acquire"), Py_val::mk_nfun(Symbol::get("acquire"), 1, native::acquire)); 
     99genv.set_sym(Symbol::get("release"), Py_val::mk_nfun(Symbol::get("release"), 1, native::release)); 
     100genv.set_sym(Symbol::get("wait"), Py_val::mk_nfun(Symbol::get("wait"), 1, native::wait)); 
     101genv.set_sym(Symbol::get("notify"), Py_val::mk_nfun(Symbol::get("notify"), 1, native::notify)); 
     102genv.set_sym(Symbol::get("notifyAll"), Py_val::mk_nfun(Symbol::get("notifyAll"), 1, native::notifyAll)); 
     103genv.set_sym(Symbol::get("get_rawaddr"), Py_val::mk_nfun(Symbol::get("get_rawaddr"), 1, native::get_rawaddr)); 
     104genv.set_sym(Symbol::get("make_sockaddr"), Py_val::mk_nfun(Symbol::get("make_sockaddr"), 1, native::make_sockaddr)); 
     105genv.set_sym(Symbol::get("py_socket"), Py_val::mk_nfun(Symbol::get("py_socket"), 0, native::py_socket)); 
     106genv.set_sym(Symbol::get("py_bind"), Py_val::mk_nfun(Symbol::get("py_bind"), 2, native::py_bind)); 
     107genv.set_sym(Symbol::get("py_listen"), Py_val::mk_nfun(Symbol::get("py_listen"), 1, native::py_listen)); 
     108genv.set_sym(Symbol::get("py_accept"), Py_val::mk_nfun(Symbol::get("py_accept"), 2, native::py_accept)); 
     109genv.set_sym(Symbol::get("py_recv"), Py_val::mk_nfun(Symbol::get("py_recv"), 1, native::py_recv)); 
     110genv.set_sym(Symbol::get("py_send"), Py_val::mk_nfun(Symbol::get("py_send"), 2, native::py_send)); 
     111genv.set_sym(Symbol::get("py_close"), Py_val::mk_nfun(Symbol::get("py_close"), 1, native::py_close)); 
  • lang/cplusplus/minipy/trunk/etc/gen_bootstrap.rb

    r14995 r15031  
    9999                [:ntv_random, -1], 
    100100                [:sys_sleep, 1], 
     101 
     102                [:mutex, 0], 
     103                [:lock, 1], 
     104                [:unlock, 1], 
     105 
     106                [:condition, 1], 
     107                [:acquire, 1], 
     108                [:release, 1], 
     109                [:wait, 1], 
     110                [:notify, 1], 
     111                [:notifyAll, 1], 
     112 
     113                [:get_rawaddr, 1], 
     114 
     115                [:make_sockaddr, 1], 
     116                [:py_socket, 0], 
     117                [:py_bind, 2], 
     118                [:py_listen, 1], 
     119                [:py_accept, 2], 
     120                [:py_recv, 1], 
     121                [:py_send, 2], 
     122                [:py_close, 1], 
    101123               ] 
    102124 
  • lang/cplusplus/minipy/trunk/native.cpp

    r14995 r15031  
    15121512    return ret; 
    15131513} 
     1514 
     1515py_val_t native::mutex(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1516                   py_val_t * a){ 
     1517    return Py_val::mk_mutex(); 
     1518} 
     1519 
     1520py_val_t native::lock(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1521                   py_val_t * a){ 
     1522    if(!Py_val::is_mutex(a[0])){ 
     1523        runtime_error(bt, p, "type error : lock() requires mutex."); 
     1524    } 
     1525 
     1526    PTH_ASSERT(pthread_mutex_lock(&a[0]->u.mutex->mutex)); 
     1527 
     1528    return Py_val::mk_none(); 
     1529} 
     1530 
     1531py_val_t native::unlock(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1532                   py_val_t * a){ 
     1533    if(!Py_val::is_mutex(a[0])){ 
     1534        runtime_error(bt, p, "type error : unlock() requires mutex."); 
     1535    } 
     1536 
     1537    PTH_ASSERT(pthread_mutex_unlock(&a[0]->u.mutex->mutex)); 
     1538 
     1539    return Py_val::mk_none(); 
     1540} 
     1541 
     1542py_val_t native::condition(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1543                           py_val_t * a){ 
     1544     
     1545    if (!Py_val::is_mutex(a[0])){ 
     1546        runtime_error(bt, p, "type error : condition() requires mutex."); 
     1547    } 
     1548 
     1549    return Py_val::mk_cond(a[0]); 
     1550} 
     1551 
     1552py_val_t native::acquire(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1553                  py_val_t * a){ 
     1554    if(!Py_val::is_cond(a[0])){ 
     1555        runtime_error(bt, p, "type error : acquire() requires condition value."); 
     1556    } 
     1557 
     1558    PTH_ASSERT(pthread_mutex_lock(&a[0]->u.cond->py_mutex->u.mutex->mutex)); 
     1559 
     1560    return Py_val::mk_none(); 
     1561} 
     1562 
     1563py_val_t native::release(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1564                  py_val_t * a){ 
     1565    if(!Py_val::is_cond(a[0])){ 
     1566        runtime_error(bt, p, "type error : release() requires condition value."); 
     1567    } 
     1568 
     1569    PTH_ASSERT(pthread_mutex_unlock(&a[0]->u.cond->py_mutex->u.mutex->mutex)); 
     1570 
     1571    return Py_val::mk_none(); 
     1572} 
     1573 
     1574py_val_t native::wait(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1575                  py_val_t * a){ 
     1576 
     1577    if(!(Py_val::is_cond(a[0]))){ 
     1578        runtime_error(bt, p, "type error : wait() requires condition value and mutex."); 
     1579    } 
     1580 
     1581    PTH_ASSERT(pthread_cond_wait(&a[0]->u.cond->cond 
     1582                                 , &a[0]->u.cond->py_mutex->u.mutex->mutex)); 
     1583     
     1584    return Py_val::mk_none(); 
     1585} 
     1586 
     1587py_val_t native::notify(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1588                  py_val_t * a){ 
     1589    if(!(Py_val::is_cond(a[0]))){ 
     1590        runtime_error(bt, p, "type error : notify() requires condiiton value."); 
     1591    } 
     1592 
     1593    PTH_ASSERT(pthread_cond_signal(&a[0]->u.cond->cond)); 
     1594 
     1595    return Py_val::mk_none(); 
     1596} 
     1597 
     1598py_val_t native::notifyAll(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1599                  py_val_t * a){ 
     1600    if(!(Py_val::is_cond(a[0]))){ 
     1601        runtime_error(bt, p, "type error : notifyAll() requires condition value."); 
     1602    } 
     1603 
     1604    PTH_ASSERT(pthread_cond_broadcast(&a[0]->u.cond->cond)); 
     1605 
     1606    return Py_val::mk_none(); 
     1607} 
     1608 
     1609py_val_t native::make_sockaddr(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1610                  py_val_t * a){ 
     1611    if (!Py_val::is_int(a[0])){ 
     1612        runtime_error(bt, p, "type error : make_sockaddr() requires integer as port number."); 
     1613    } 
     1614    return Py_val::mk_sockaddr(a[0]); 
     1615} 
     1616 
     1617py_val_t native::py_socket(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1618                  py_val_t * a){ 
     1619    int fd = socket(AF_INET, SOCK_STREAM, 0); 
     1620     
     1621    return Py_val::mk_int(fd); 
     1622} 
     1623 
     1624py_val_t native::py_bind(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1625                      py_val_t * a){ 
     1626    if (!Py_val::is_int(a[0])){ 
     1627        runtime_error(bt, p, "type error : bind() requires integer as socket."); 
     1628    } 
     1629    if (!Py_val::is_sockaddr(a[1])){ 
     1630        runtime_error(bt, p, "type error : bind() requires sockaddr."); 
     1631    } 
     1632 
     1633    int ret = bind(getint(a[0]), (struct sockaddr *)a[1]->u.addr 
     1634                   ,sizeof(*a[1]->u.addr)); 
     1635    return Py_val::mk_int(ret); 
     1636} 
     1637 
     1638py_val_t native::py_listen(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1639                      py_val_t * a){ 
     1640    if (!Py_val::is_int(a[0])){ 
     1641        runtime_error(bt, p, "type error : listen() requires integer as socket."); 
     1642    } 
     1643 
     1644    int ret = listen(getint(a[0]), 64); 
     1645    return Py_val::mk_int(ret); 
     1646} 
     1647 
     1648py_val_t native::py_accept(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1649                        py_val_t * a){ 
     1650    if (!Py_val::is_int(a[0])){ 
     1651        runtime_error(bt, p, "type error : accept() requires integer as socket."); 
     1652    } 
     1653    if (!Py_val::is_sockaddr(a[1])){ 
     1654        runtime_error(bt, p, "type error : accept() requires sockaddr."); 
     1655    } 
     1656 
     1657    socklen_t socklen; 
     1658    int conn_fd = accept(getint(a[0]) 
     1659                         , (struct sockaddr *)a[1]->u.addr 
     1660                         , &socklen); 
     1661 
     1662    return Py_val::mk_int(conn_fd); 
     1663} 
     1664 
     1665py_val_t native::py_recv(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1666                      py_val_t * a){ 
     1667    if (!Py_val::is_int(a[0])){ 
     1668        runtime_error(bt, p, "type error : recv() requires integer as connection file discriptor."); 
     1669    } 
     1670     
     1671    char buf[4096]; 
     1672    int len = recv(getint(a[0]), buf, 4096, 0); 
     1673 
     1674    if (len < 0){ 
     1675        runtime_error(bt, p, "recv error"); 
     1676        exit(1); 
     1677    } 
     1678 
     1679    string str(buf); 
     1680    return Py_val::mk_string(str); 
     1681} 
     1682 
     1683py_val_t native::py_send(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1684                      py_val_t * a){ 
     1685    if (!Py_val::is_int(a[0])){ 
     1686        runtime_error(bt, p, "type error : send() requires integer as connection file discriptor."); 
     1687    } 
     1688    if (!Py_val::is_string(a[1])){ 
     1689        runtime_error(bt, p, "type error : send() requires string."); 
     1690    } 
     1691 
     1692    return Py_val::mk_int(send(getint(a[0]), a[1]->u.s->c_str(), a[1]->u.s->length(), 0)); 
     1693} 
     1694 
     1695py_val_t native::py_close(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1696                      py_val_t * a){ 
     1697    if (!Py_val::is_int(a[0])){ 
     1698        runtime_error(bt, p, "type error : close() requires integer as connection file discriptor."); 
     1699    } 
     1700 
     1701    return Py_val::mk_int(close(getint(a[0]))); 
     1702} 
     1703 
     1704py_val_t native::get_rawaddr(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     1705                             py_val_t * a){ 
     1706    return Py_val::mk_int((int) a[0]); 
     1707} 
     1708 
     1709 
  • lang/cplusplus/minipy/trunk/native.hpp

    r14995 r15031  
    1010#include "env.hpp" 
    1111#include "tivi.hpp" 
     12 
     13#include <arpa/inet.h> 
     14#include <sys/socket.h> 
     15 
     16#define DEFINE_PY_FUNC(funcname)                                \ 
     17    py_val_t funcname(ConsStack<Stack_trace_entry*> * bt        \ 
     18                      ,const SrcPos & p,                        \ 
     19                      py_val_t * a) 
    1220 
    1321namespace native{ 
     
    246254 
    247255    // experimental multithread implementation 
     256    py_val_t mutex(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     257                   py_val_t * a); 
     258    py_val_t lock(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     259                  py_val_t * a); 
     260    py_val_t unlock(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     261                    py_val_t * a); 
     262 
     263    py_val_t condition(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     264                  py_val_t * a); 
     265    py_val_t acquire(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     266                  py_val_t * a); 
     267    py_val_t release(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     268                  py_val_t * a); 
     269    py_val_t wait(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     270                  py_val_t * a); 
     271    py_val_t notify(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     272                    py_val_t * a); 
     273    py_val_t notifyAll(ConsStack<Stack_trace_entry*> * bt,const SrcPos & p, 
     274                       py_val_t * a); 
     275    DEFINE_PY_FUNC(get_rawaddr); 
     276 
     277    // networking 
     278    DEFINE_PY_FUNC(make_sockaddr); 
     279 
     280    DEFINE_PY_FUNC(py_socket); 
     281    DEFINE_PY_FUNC(py_bind); 
     282    DEFINE_PY_FUNC(py_listen); 
     283    DEFINE_PY_FUNC(py_accept); 
     284    DEFINE_PY_FUNC(py_recv); 
     285    DEFINE_PY_FUNC(py_send); 
     286    DEFINE_PY_FUNC(py_close); 
    248287} 
    249288 
  • lang/cplusplus/minipy/trunk/pyvalues.cpp

    r14995 r15031  
    584584               , (uint)pyval->u.n->f); 
    585585        break; 
     586    case py_type_thread: 
     587        printf("<thread>"); 
     588        break; 
    586589    default: 
    587590        cerr << "never reaches here at " << __FILE__ << ":" << __LINE__; exit(1); 
     
    648651bool Py_val::is_thread(py_val_t pyval){ 
    649652    return is_boxed(pyval) && pyval->type == py_type_thread; 
     653} 
     654 
     655bool Py_val::is_mutex(py_val_t pyval){ 
     656    return is_boxed(pyval) && pyval->type == py_type_mutex; 
     657} 
     658 
     659bool Py_val::is_cond(py_val_t pyval){ 
     660    return is_boxed(pyval) && pyval->type == py_type_cond; 
     661} 
     662 
     663bool Py_val::is_sockaddr(py_val_t pyval){ 
     664    return is_boxed(pyval) && pyval->type == py_type_sockaddr; 
    650665} 
    651666 
     
    979994 
    980995 
     996py_val_t Py_val::mk_mutex(){ 
     997    py_val_t ret; 
     998 
     999    ret = Py_val::alloc_boxed(py_type_mutex); 
     1000    Py_mutex * mutex = new Py_mutex(); 
     1001    ret->u.mutex = mutex; 
     1002 
     1003    return ret; 
     1004} 
     1005 
     1006 
     1007py_val_t Py_val::mk_cond(py_val_t mutex){ 
     1008    py_val_t ret; 
     1009 
     1010    ret = Py_val::alloc_boxed(py_type_cond); 
     1011    Py_cond * cond = new Py_cond(mutex); 
     1012    ret->u.cond = cond; 
     1013     
     1014    return ret; 
     1015} 
     1016 
     1017py_val_t Py_val::mk_sockaddr(py_val_t port){ 
     1018    py_val_t ret; 
     1019 
     1020    ret = Py_val::alloc_boxed(py_type_sockaddr); 
     1021    ret->u.addr = new sockaddr_in(); 
     1022    ret->u.addr->sin_family = AF_INET; 
     1023    ret->u.addr->sin_addr.s_addr = htonl(INADDR_ANY); 
     1024    ret->u.addr->sin_port = htons(getint(port)); 
     1025     
     1026    return ret; 
     1027} 
     1028 
     1029 
    9811030/* 
    9821031 * 辞書式! 
     
    12001249    this->func = func; 
    12011250    this->joined = false; 
    1202     pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER; 
    1203     this->join_mutex = mt; 
    1204     pthread_cond_t cnd = PTHREAD_COND_INITIALIZER; 
    1205     this->join_cond = cnd; 
     1251 
     1252    // pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER; 
     1253//     this->join_mutex = mt; 
     1254//     pthread_cond_t cnd = PTHREAD_COND_INITIALIZER; 
     1255//     this->join_cond = cnd; 
    12061256 
    12071257    PTH_ASSERT(pthread_mutex_init(&this->join_mutex, NULL)); 
     
    12121262     
    12131263} 
     1264 
     1265Py_mutex::Py_mutex(){ 
     1266    pthread_mutex_init(&this->mutex, NULL); 
     1267} 
     1268 
     1269Py_cond::Py_cond(py_val_t mutex){ 
     1270    this->py_mutex = mutex; 
     1271    pthread_cond_init(&this->cond, NULL); 
     1272} 
  • lang/cplusplus/minipy/trunk/pyvalues.hpp

    r14995 r15031  
    1717#include "thread.hpp" 
    1818 
     19#include <sys/socket.h> 
     20#include <netinet/in.h> 
     21 
    1922class Py_val; 
    2023class Py_ifun; 
     
    2730class Py_tuple; 
    2831class Py_thread; 
     32class Py_mutex; 
     33class Py_cond; 
    2934 
    3035/* stack trace */ 
     
    95100    py_type_mutex, 
    96101    py_type_cond, 
     102    py_type_sockaddr, 
    97103} py_type_t; 
    98104 
     
    157163        Py_tuple * nl;  /* tuple or list(in the future) */ 
    158164        Py_thread * th; 
     165        Py_mutex * mutex; 
     166        Py_cond * cond; 
     167        sockaddr_in * addr; 
    159168    } u; 
    160169 
     
    176185    static bool is_number(py_val_t pyval); // is int or float 
    177186    static bool is_thread(py_val_t pyval); 
     187    static bool is_mutex(py_val_t pyval); 
     188    static bool is_cond(py_val_t pyval); 
     189    static bool is_sockaddr(py_val_t pyval); 
    178190 
    179191    /* 型チェックをし、Py_val_tから値を取り出す. 
     
    219231     
    220232    static py_val_t mk_thread(py_val_t func); 
     233    static py_val_t mk_mutex(); 
     234    static py_val_t mk_cond(py_val_t mutex); 
     235 
     236    static py_val_t mk_sockaddr(py_val_t port); 
    221237 
    222238#define mkint(var) Py_val::mk_int(var) 
     
    378394public: 
    379395    pthread_mutex_t mutex; 
    380      
    381 } 
    382  
     396 
     397    Py_mutex(); 
     398}; 
     399 
     400class Py_cond { 
     401public: 
     402    pthread_cond_t cond; 
     403    py_val_t py_mutex; 
     404 
     405    Py_cond(py_val_t mutex); 
     406}; 
    383407#endif 
  • lang/cplusplus/minipy/trunk/testdata-parser/thread/basic.py

    r14995 r15031  
    11 
    22x = 0 
     3lk = mutex() 
    34 
    45def job(): 
    56  global x 
     7  global lk 
    68  for i in range(0,100000): 
     9    lk.lock() 
    710    x = x + 1 
     11    y = y + 1 
     12    lk.unlock() 
    813 
    9 th_a = start_new_thread(print_string, ("hoge",)) 
    10 th_b = start_new_thread(print_string, ("fuga",)) 
     14th_a = start_new_thread(job, ()) 
     15th_b = start_new_thread(job, ()) 
    1116 
    1217thread_join(th_a) 
     
    1419 
    1520print x 
     21print y 
  • lang/cplusplus/minipy/trunk/tivi.cpp

    r14995 r15031  
    712712        if (INST == VM_GREF_CALL){ 
    713713            if ((f = TIVI_GREF(TIVI_FETCH_OPERAND())) == py_val_not_found){ 
    714                 runtime_error("no such function ", bt, PC); 
     714                runtime_error("no such function " + *genv_rev[(int)TIVI_FETCH_OPERAND()], bt, PC); 
    715715            } 
    716716            bt = CONS_STACK(new Stack_trace_entry(*genv_rev[(int)this->insns[PC].operand] 
     
    10601060     
    10611061    delete(args); 
     1062 
     1063    return NULL; 
    10621064} 
    10631065