• Re: 渣淮4发生油门没反应

    iev5 发生过一次, 去八达岭长城, 一路上坡; 开的相对比较浪; 快到的时候道路变窄, 车多了, 踩刹车就很频繁了; 然后不知啥时候起油门就开始软绵绵的, 到最后, 几乎踩到底也只能维持了 20 公里左右的时速, 就这么一步步蹭到了停车场。 回去的时候发现又好使了; 个人估计是频繁放电, 刹车, 放电, 刹车导致电池出了什么变化限制功率输出了。

    现在开汉也隐隐约约有点感觉, 就是一开始启动时动力十足, 但开了一会后, 就觉得似乎没一开始那么加速灵敏; 也不知道是不是准确的

    【 在 sunglass 的大作中提到: 】

    : 江淮iev4,5年半,8万公里,昨天在小区里低速转圈停车时候会发生好几次踩了油门像没踩一样,必须踩一下刹车彻底停住了,再踩油门就正常加速了

    : 这是啥问题?有朋友遇到过吗?

    : 打算榨干最后一点实用价值,看看能不能度过下一个冬天。目前冬天续航还是能有100,夏天没有150也有140,很稳定,大大超出预期。

    : ...................

    02月28日
  • Re:看到上了十大头条过来看看这个版

    已站短 莫辜负

    发自「今日水木 on RVL-AL09」

    【 在 qiermao 的大作中提到: 】

    : 现在已婚才三十三。不知道以后会不会跟这个版搭边。离婚和约炮,骗炮他们有顺序吗?各自喜欢就好吧,何必思索对错。一个巴掌拍不响,做自己喜欢做的事就好啦。

    : --

    02月27日
  • Re:蜘蛛女侠

    杨晨晨还是包臀裙黑丝吊带袜高跟鞋好看

    发自「今日水木 on RVL-AL09」

    【 在 cca 的大作中提到: 】

    : [upload][/upload]

    : [upload][/upload]

    : [upload][/upload]

    : [upload][/upload]

    : [upload][/upload]

    : [upload][/upload]

    : [upload][/upload]

    : --

    02月26日
  • Re:转电饭煲, 电压力锅
    loading ...

    电压力锅

    发自「今日水木 on RVL-AL09」

    【 在 zylthinking2 的大作中提到: 】

    : 都用过一段时间, 然后各种原因, 比如年终奖啊, 觉得哪里功能不如其他的啊什么的换了新的, 旧的就搁置了。

    : 现在有1个电饭煲, 1个电压力锅, 实在占地, 便宜甩了, 都20吧。 原价大概都是150 到 200 之间的样子。

    : 其实各有两个, 有人舍不得都卖出去, 一点要留一个.....

    : 先问问有没有人要, 有人感兴趣随后上照片, 现在懒得折腾出来拍照。

    : 清河附近

    : 电压力锅是美的的 电饭煲是九阳的 型号不知道怎么看, 看图片吧

    : 发自「今日水木 on RVL-AL09」

    : --

    : 她就只是反复的向人说她悲惨的故事,常常引住了三五个人来听她。但不久,大家也都听得纯熟了,便是最慈悲的念佛的老太太们,眼里也再不见有一点泪的痕迹。后来全镇的人们几乎都能背诵她的话,一听到就烦厌得头痛。

    : “我真傻,真的,”她开首说。

    : “是的,你是单知道雪天野兽在深山里没有食吃,才会到村里来的。”他们立即打断她的话,走开去了。

    : [upload][/upload]

    02月24日
  • Re:转电饭煲, 电压力锅
    loading ...

    电饭煲

    发自「今日水木 on RVL-AL09」

    【 在 zylthinking2 的大作中提到: 】

    : 都用过一段时间, 然后各种原因, 比如年终奖啊, 觉得哪里功能不如其他的啊什么的换了新的, 旧的就搁置了。

    : 现在有1个电饭煲, 1个电压力锅, 实在占地, 便宜甩了, 都20吧。 原价大概都是150 到 200 之间的样子。

    : 其实各有两个, 有人舍不得都卖出去, 一点要留一个.....

    : 先问问有没有人要, 有人感兴趣随后上照片, 现在懒得折腾出来拍照。

    : 清河附近

    : 电压力锅是美的的 电饭煲是九阳的 型号不知道怎么看, 看图片吧

    : 发自「今日水木 on RVL-AL09」

    : --

    : 她就只是反复的向人说她悲惨的故事,常常引住了三五个人来听她。但不久,大家也都听得纯熟了,便是最慈悲的念佛的老太太们,眼里也再不见有一点泪的痕迹。后来全镇的人们几乎都能背诵她的话,一听到就烦厌得头痛。

    : “我真傻,真的,”她开首说。

    : “是的,你是单知道雪天野兽在深山里没有食吃,才会到村里来的。”他们立即打断她的话,走开去了。

    : [upload][/upload]

    02月24日
  • Re:是我作吗

    已站短 莫相负

    发自「今日水木 on RVL-AL09」

    【 在 wyf555 的大作中提到: 】

    : 17年前谈恋爱时如胶似漆,生大娃以后婆媳矛盾导致夫妻矛盾,老公开始不主动亲热,十几年前我就开始抱怨他对我冷淡,他逐渐的越来越不愿意跟我有亲昵的行为,这十几年期间他几乎从不主动提出同房,为此我从开始的抱怨逐步到生气,再到发火,到冷战,反反复复数不清多少次为此生气,他生理没有问题,每次都说他没有意愿,不过性生活也没啥。到现在几个月一次要我不提出他是不会主动的,平时手都不拉一下,几年前生了二娃自此一直分房睡。如果现在他拉我一下手,拥抱一下我我可能都会觉得很尴尬,别扭。因为很多年他已经对我没有任何亲昵的动作了,不知道为什么夫妻之间竟然处成了陌生人。生日,情人节三八,结婚纪念日他越来越淡忘,就当不知道似的,更别说有礼物了,我不知道他为什么如此冷漠。我提过意见,希望他节日有所表示,但是依然无动于衷,对他我现在已经失望透顶。今早,终于把他叫过来,单方面宣布,以后我要在外面找人了,请他有所心里准备,反正现在跟离婚也没啥区别,除了一起养娃外。他说是我太骚,太贱,为什么非要性生活,做那事就这么感兴趣吗?我说咱们三四个月一次,每次还都是我吵架争取来的,是我骚吗?还是他有问题,我说这个家,从结婚到现在,什么不是我自己努力奋斗来的,大房子,两娃,现在的收入…我没有拿过他家一分钱,婚后住在两人共同买的房子里面居然被她妈要挟,不拿钱给他妈买房子他妈就不走,这么多年我一个女人经常熬夜加班收入不比他低,还生了二娃,加班挣钱埋怨我不带娃,他父母一直跟我们带娃,白天他们带,晚上我再苦再累也是我哄娃睡觉,他自己跑隔壁去睡,怕娃打扰他休息,但是他反倒经常埋怨我轻松,不带娃。林林总总,掰开来说太多说不完,总得就是他觉得老夫老妻不需要了,我们也就四十多一点,我觉得他现在越来越冷漠,对我不好,我就是他免费的保姆,还能给他挣钱买房。今早我也说了,即便你现在主动要求同房,我也不会同意了,已经伤着了,以后我不会主动要求了,也希望他别碰我,我现在已经恶心他了。

    : --

    02月24日
  • 转电饭煲, 电压力锅
    loading ...

    都用过一段时间, 然后各种原因, 比如年终奖啊, 觉得哪里功能不如其他的啊什么的换了新的, 旧的就搁置了。

    现在有1个电饭煲, 1个电压力锅, 实在占地, 便宜甩了, 都20吧。 原价大概都是150 到 200 之间的样子。

    其实各有两个, 有人舍不得都卖出去, 一点要留一个.....

    先问问有没有人要, 有人感兴趣随后上照片, 现在懒得折腾出来拍照。

    清河附近

    电压力锅是美的的 电饭煲是九阳的 型号不知道怎么看, 看图片吧

    发自「今日水木 on RVL-AL09」

    02月22日
  • Re:[转让]八成新实木衣柜餐桌椅书桌床头柜洗衣机冰箱等

    书桌有图吗

    发自「今日水木 on RVL-AL09」

    【 在 a19880910 的大作中提到: 】

    : 品相都还可以,安贞门附近自提,有电梯可加v844689883

    : --

    : [upload][/upload]

    02月09日
  • Re:找工作, 大家看一下, 这样的代码水平如何

    若谈论技术, 那就陷入细节了

    不过我可以给你分析一下里面需要解决的问题

    1. 你不可能用 channel 简单实现的了

    你可以假设一个数据库字段自增操作, 之所以假设数据库, 是因为这是一个昂贵操作。

    以下假设都是基于我面临的问题, 所以不用怀疑我下面描述的合理性, 只管接受这些假设及要求即可。

    现在有若干个比如 1000 个协程每个都对该字段 +1 并返回自增后的数字, 因为这是一个昂贵操作, 因此现在要求其中只允许一个协程代理全部的操作, 对其 +1000。

    剩下的只需要获得操作的结果 N,

    然后这 1000 个协程通过合适的逻辑, 分别返回 [N - 999, N] 之间的一个数字, 以保证返回结果和他亲自调用 +1 并返回自增后的结果一样。

    这里的要求是在操作过程中, 仍然会时不时有新的协程对这个字段做 +1 操作, 但必须等+1000 结束后才能进行;

    那么等 +1000 结束, 可能有 2 群协程, 一群是 +1000 后拿到结果直接返回的, 另一群是 +1000 结束后, 对字段继续 +1 的;

    然后还有要求, 第一群需要同时唤醒, 以尽量降低调度延迟; 第二群里面的需要只唤醒一个, 让其代理对第二群里面的所有自增操作; 自然第一群那些唤醒后分行李的协程不能阻塞第二群被唤醒的那个协程

    当然, 这里面没有保证这一群必须是 1000 或某个固定数字, 因为有可能再也没有 +1 的协程到来了, 第二群唤醒的那个协程必须保证只代理它在检查第二群那一瞬间看到的那些 +1, 后继的组成第三群, 不能代理

    你用 channel 实现试试, 或者除了别用我的办法, 你用你能想到的任何办法试试, 我也好奇还有没有更优实现。

    2. 这里面没有 bug, 你若认为有明显竞态, 说明你没有看懂

    : 简单一个,SwapPointer不和LoadPointer配对使用就会带来问题

    你甚至都没有看到 LoadPointer 在哪里, 或者你没有意识到另一个swap pointer 操作的目标根本没有要读的必要, 简单说, 就是 lock 返回值会告诉caller 是进入了临界区还是单纯分行李, 分行李的不需要 unlock.

    unlock 定义的语意是 只要当前锁确实是上锁的, 则解锁, 并不是只有持有锁的才能解锁,golang mutex.unlock 同样是这个表现。  里面的swap pointer 只是为了保证如果已经解锁了, 则不做任何事。

    你可以将你的理解及认为的解决方案说出来, 或者将你认为的 nr 有问题到底怎么有问题说出来

    【 在 MyWorkLife 的大作中提到: 】

    : 不评价你的遭遇

    : 但是代码里面问题不少

    : 最大的问题是思维方式

    : ...................

    02月03日
  • 想换工作

    有没有贵人肯帮一把

    https://www.newsmth.net/nForum/#!article/Career_Upgrade/775020

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    https://github.com/zylthinking/codec 这是我用最短路径算法实现的音视频转码器, 我用转码将编码, 解码, 转码三个概念统一成一个; 里面会有一系列 media_unit, 每个接收一种(或一类)格式的输入, 输出一种(或一类)格式的输出; 使用时指定一个源格式, 一个目标格式, 只要存在一个链条将将源, 目标格式连接起来, 就能做到将源格式转换成目标格式

    https://github.com/zylthinking/fdset 这是我自己写的网络框架, 本来支持 linux/freebsd/windows 三种平台, 分别使用epoll/kqueue/iocp 机制; 后来不再写 ios/windows 端了, 因此不再维护了, 剩下 linux 版本

    https://github.com/zylthinking/hooker 这是我写着玩的一个 inline asm hooker; 可以替换系统函数为自己的实现, 也在部分函数上能够再跳回到原函数执行; 跳转回原函数不完美, 主要是原函数有 当前指令地址偏移量做相对寻址, 则搞不定, 因为我将目标函数前几个指令拷贝到另一个地址上去执行了, 因此, 相对寻址就乱了

    https://github.com/zylthinking/godefer-toy 这个也是个玩具, 用汇编实现了 golang 的 defer 机制, 也和编译器有关系; 玩票性质

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    这是以上面的 golang 无锁链表为基础实现的公平mutex锁

    所谓公平 mutex 锁, 指的是获得锁的顺序与请求锁的顺序一致

    package goc

    import (

    "fmt"

    "os"

    "runtime"

    "sync"

    "sync/atomic"

    "unsafe"

    )

    type seq_node struct {

    LkfNode

    mux sync.Mutex

    }

    type SeqLock struct {

    nr     int64

    wl     LkfList

    head   *LkfNode

    holder *seq_node

    mux    sync.Mutex

    }

    func NewSeqLock() *SeqLock {

    seqlock := &SeqLock{}

    LkfInit(&seqlock.wl)

    return seqlock

    }

    func (this *SeqLock) Lock() {

    var node seq_node

    LkfNodePut(&this.wl, &node.LkfNode)

    n := atomic.AddInt64(&this.nr, 1)

    if n > 1 {

    node.mux.Lock()

    node.mux.Lock()

    if this.holder != &node {

    fmt.Println("Bugs in SeqLock")

    os.Exit(1)

    }

    } else {

    this.mux.Lock()

    this.head = LkfNodeGet(&this.wl)

    this.holder = this.next()

    }

    }

    func (this *SeqLock) next() *seq_node {

    LABEL:

    lkfn := LkfNodeNext(this.head)

    if lkfn == nil {

    runtime.Gosched()

    goto LABEL

    }

    return (*seq_node)(unsafe.Pointer(lkfn))

    }

    func (this *SeqLock) Unlock() {

    n := atomic.AddInt64(&this.nr, -1)

    if n == 0 {

    this.mux.Unlock()

    return

    }

    // 本批次最后一个 unlock

    // 但 nr > 0 说明有其他的 Lock 已经进入 wl

    // 获取一个新的批次

    // 可以断言批次一定不为空

    if this.head == &this.holder.LkfNode {

    this.head = LkfNodeGet(&this.wl)

    }

    this.holder = this.next()

    this.holder.mux.Unlock()

    }

    【 在 zylthinking2 的大作中提到: 】

    : 这是无锁链表的 golang 版本

    : package goc

    : ...................

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    这是无锁链表的 golang 版本

    package goc

    import (

    "fmt"

    "runtime"

    "sync/atomic"

    "unsafe"

    )

    type LkfNode struct {

    next      unsafe.Pointer

    Container interface{}

    }

    func LknInit(node *LkfNode, container interface{}) {

    node.Container = container

    }

    type LkfList struct {

    root LkfNode

    tail unsafe.Pointer

    }

    func (this *LkfList) Explain() {

    for cur := this.root.next; cur != nil; {

    lkfn := (*LkfNode)(cur)

    fmt.Printf("%p ->", lkfn)

    cur = lkfn.next

    }

    fmt.Printf("nil\n")

    }

    func init() {

    var node LkfNode

    lkf_node_offset = unsafe.Offsetof(node.next)

    }

    var lkf_node_offset uintptr = 0

    func LkfInit(list *LkfList, addr ...interface{}) {

    list.root.next = nil

    if len(addr) != 0 {

    LknInit(&list.root, addr[0])

    }

    list.tail = unsafe.Pointer(&list.root.next)

    }

    func LkfNodePut(list *LkfList, node *LkfNode) {

    node.next = nil

    ptr := atomic.SwapPointer(&list.tail, unsafe.Pointer(&node.next))

    *(*unsafe.Pointer)(ptr) = unsafe.Pointer(node)

    }

    func LkfNodeGet(list *LkfList) *LkfNode {

    first := atomic.SwapPointer(&list.root.next, nil)

    ptr := (*LkfNode)(first)

    if ptr == nil {

    return nil

    }

    last := atomic.SwapPointer(&list.tail, unsafe.Pointer(&list.root.next))

    *(*unsafe.Pointer)(last) = first

    ptr = (*LkfNode)(unsafe.Pointer(uintptr(last) - lkf_node_offset))

    runtime.KeepAlive(last)

    return ptr

    }

    func LkfNodeNext(node *LkfNode) *LkfNode {

    ptr := (*LkfNode)(node.next)

    if ptr == nil || ptr.next == nil {

    return nil

    }

    if ptr != node {

    node.next = ptr.next

    }

    ptr.next = nil

    return ptr

    }

    type PContext struct {

    List LkfList

    stat int32

    }

    func ProcInit(ctx *PContext) {

    LkfInit(&ctx.List, ctx)

    }

    func ProcEnter(ctx *PContext, node *LkfNode) bool {

    LkfNodePut(&ctx.List, node)

    return atomic.CompareAndSwapInt32(&ctx.stat, 0, 1)

    }

    func ProcLeave(ctx *PContext) bool {

    atomic.StoreInt32(&ctx.stat, 0)

    tail := (*unsafe.Pointer)(atomic.LoadPointer(&ctx.List.tail))

    if tail == &ctx.List.root.next {

    return true

    }

    return !atomic.CompareAndSwapInt32(&ctx.stat, 0, 1)

    }

    【 在 zylthinking2 的大作中提到: 】

    : 这是一个我自己发明的无锁链表实现

    : 特点是多写一读情况下, 不考虑 CPU 指令的本身实现, 则是 O(1) 的, 没有任何循环

    : ...................

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    这是一个我自己发明的无锁链表实现

    特点是多写一读情况下, 不考虑 CPU 指令的本身实现, 则是 O(1) 的, 没有任何循环

    #ifndef lkf_h

    #define lkf_h

    typedef struct lkf_node {

    struct lkf_node* next;

    } lkf_node;

    typedef struct lkf_list {

    struct lkf_node root;

    struct lkf_node** tail;

    } lkf_list;

    #define LKF_INIT(name) {.root = {NULL}, .tail = &(name.root.next)}

    #define LKF_LIST(name) \

    struct lkf_list name = LKF_INIT(name)

    #define INIT_LKF(name) \

    do { \

    typeof(name) lkf = name; \

    lkf->root.next = NULL; \

    lkf->tail = &(lkf->root.next); \

    } while (0)

    static inline void lkf_node_put(struct lkf_list* list, struct lkf_node* node)

    {

    node->next = NULL;

    struct lkf_node** ptr = __sync_lock_test_and_set(&(list->tail), &(node->next));

    *ptr = node;

    }

    static inline struct lkf_node* lkf_node_get_one(struct lkf_list* list)

    {

    struct lkf_node* head = __sync_lock_test_and_set(&(list->root.next), NULL);

    if (head == NULL) {

    return NULL;

    }

    struct lkf_node* next = head->next;

    if (next != NULL) {

    list->root.next = next;

    head->next = head;

    return head;

    }

    int b = __sync_bool_compare_and_swap(&(list->tail), &(head->next), &(list->root.next));

    if (b) {

    head->next = head;

    return head;

    }

    list->root.next = head;

    return NULL;

    }

    static inline struct lkf_node* lkf_node_get(struct lkf_list* list)

    {

    struct lkf_node* ptr = __sync_lock_test_and_set(&(list->root.next), NULL);

    if (ptr == NULL) {

    return NULL;

    }

    struct lkf_node** last = __sync_lock_test_and_set(&(list->tail), &(list->root.next));

    *last = ptr;

    return *last;

    }

    static inline struct lkf_node* lkf_node_next(struct lkf_node* node)

    {

    struct lkf_node* ptr = node->next;

    if (ptr == NULL || ptr->next == NULL) {

    return NULL;

    }

    if (ptr == node) {

    return ptr;

    }

    node->next = ptr->next;

    ptr->next = NULL;

    return ptr;

    }

    #ifdef __linux__

    #include <linux/futex.h>

    #include <syscall.h>

    static inline void lkf_node_put_wake(struct lkf_list* list, struct lkf_node* node)

    {

    node->next = NULL;

    struct lkf_node** ptr = __sync_lock_test_and_set(&(list->tail), &(node->next));

    if (ptr == &list->root.next) {

    while (-1 == syscall(__NR_futex, ptr, FUTEX_WAKE, 1, NULL, NULL, 0));

    }

    *ptr = node;

    }

    static inline struct lkf_node* lkf_node_get_wait(struct lkf_list* list)

    {

    struct lkf_node* ptr = __sync_lock_test_and_set(&(list->root.next), NULL);

    while (ptr == NULL) {

    syscall(__NR_futex, &list->root.next, FUTEX_WAIT, NULL, NULL, NULL, 0);

    ptr = __sync_lock_test_and_set(&(list->root.next), NULL);

    };

    struct lkf_node** last = __sync_lock_test_and_set(&(list->tail), &(list->root.next));

    *last = ptr;

    return *last;

    }

    #endif

    #if 1

    typedef struct proc_context {

    struct lkf_list list;

    int stat;

    } proc_context;

    static int proc_enter(struct proc_context* ctx, struct lkf_node* node)

    {

    lkf_node_put(&ctx->list, node);

    int n = __sync_bool_compare_and_swap(&ctx->stat, 0, 1);

    if (n == 0) {

    return -1;

    }

    return 0;

    }

    static int proc_leave(struct proc_context* ctx)

    {

    ctx->stat = 0;

    __sync_synchronize();

    if (ctx->list.tail == &ctx->list.root.next) {

    return 0;

    }

    int n = __sync_bool_compare_and_swap(&ctx->stat, 0, 1);

    if (n == 0) {

    return 0;

    }

    return -1;

    }

    #endif

    #endif

    【 在 zylthinking2 的大作中提到: 】

    : 值不值一个360 T7级别

    : 真是心寒了

    : 难道 43 岁就真的要窝窝囊囊被人欺负?

    : ...................

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    这是一个自己实现的强弱指针类似实现

    特点是本身不分强弱指针, 并且任何指针在任何时间可以将实际对象销毁

    如此可以用在线程同步中, 如果循环中获得内部指针发现返回 NULL, 则可作为一个退出标志来用

    若得到了这个内部指针, 则可以保证在使用的过程中, 肯定不会被释放

    #ifndef my_handle_h

    #define my_handle_h

    #include <stdint.h>

    #include "zyl.h"

    typedef struct my_handle {

    int ref;

    int stack;

    intptr_t detached;

    void* ptr;

    free_t free;

    } my_handle;

    static inline my_handle* handle_attach(void* ptr, free_t fp_free, const char* func, int line)

    {

    my_handle* handle = (my_handle *) debug_malloc(sizeof(my_handle), func, line);

    if (handle != NULL) {

    handle->ref = 1;

    handle->stack = 1;

    handle->ptr = ptr;

    handle->free = fp_free;

    handle->detached = 0;

    }

    return handle;

    }

    static inline void handle_put(my_handle* handle, const char* func, int line)

    {

    int n = __sync_sub_and_fetch(&(handle)->stack, 1);

    assert1(n >= 0);

    if (n == 0) {

    void* handle_ptr = (void *) __sync_lock_test_and_set(&(handle)->ptr, NULL);

    if ((handle)->free && handle_ptr) {

    (handle)->free(handle_ptr);

    }

    }

    }

    static inline void* handle_get_with(my_handle* handle, int detach, const char* func, int line)

    {

    int n = __sync_add_and_fetch(&handle->stack, 1);

    int b = __sync_bool_compare_and_swap((void **) &handle->detached, (void *) 0, (void *) (intptr_t) detach);

    if (!b) {

    handle_put(handle, func, line);

    return NULL;

    }

    void* ptr = handle->ptr;

    assert2(n > 1 && ptr != NULL, "%d, %p, caller %d@%s", n, ptr, line, func);

    return ptr;

    }

    static inline int handle_clone(my_handle* handle)

    {

    int n = __sync_add_and_fetch(&handle->ref, 1);

    assert1(n > 0);

    return n;

    }

    static inline int handle_release(my_handle* handle, const char* func, int line)

    {

    int n = __sync_sub_and_fetch(&handle->ref, 1);

    assert2(n >= 0, "%p %d:%d, caller %d@%s", handle, handle->ref, handle->stack, line, func);

    if (n > 0) {

    return n;

    }

    // it should be safe to simplely check whether detached equals 0.

    // we know __sync_xxx functions have mb() semantics, and

    // if some one set handle->detached = 1, it only can be called in

    // handle_dettach while still holds a reference of handle.

    // ok, now we have seen handle->ref = 0 above, meaning

    // we have observed the latter handle_release in handle_dettach.

    // then, the mb() assure that

    // we have observed the earlier handle_get_with(handle, 1).

    if (handle->detached == 0) {

    handle_put(handle, func, line);

    }

    assert1(handle->stack == 0);

    my_free(handle);

    return n;

    }

    static inline int handle_dettach(my_handle* handle, const char* func, int line)

    {

    void* ptr = handle_get_with(handle, 1, func, line);

    if (ptr != NULL) {

    __sync_sub_and_fetch(&handle->stack, 1);

    handle_put(handle, func, line);

    }

    return handle_release(handle, func, line);

    }

    #define handle_get(handle) handle_get_with((my_handle *) (handle), 0, __FUNCTION__, __LINE__)

    #define handle_clone(handle) handle_clone((my_handle *) handle)

    #define handle_attach(ptr, fptr) handle_attach(ptr, fptr, __FUNCTION__, __LINE__)

    #define handle_put(h) handle_put((my_handle *) h, __FUNCTION__, __LINE__)

    #define handle_release(handle) handle_release((my_handle *) (handle), __FUNCTION__, __LINE__)

    #define handle_dettach(handle) handle_dettach((my_handle *) (handle), __FUNCTION__, __LINE__)

    #endif

    【 在 zylthinking2 的大作中提到: 】

    : 值不值一个360 T7级别

    : 真是心寒了

    : 难道 43 岁就真的要窝窝囊囊被人欺负?

    : ...................

    02月03日
  • Re: 大家看一下, 这样的代码水平如何

    这是一个可以防止多个并发干一件事的锁

    能达到的语义是允许其中一个干, 然后可以将干的结果分享给其他的

    比如 10 个并发读同一个文件, 就可以让其中一个读, 其他的只取其读到的内容

    package goc

    import (

    "sync"

    "sync/atomic"

    "unsafe"

    )

    type cond struct {

    uptr unsafe.Pointer

    mux  sync.Mutex

    cond *sync.Cond

    }

    func newCond() *cond {

    cond := &cond{}

    cond.cond = sync.NewCond(&cond.mux)

    return cond

    }

    func (this *cond) wait() {

    this.mux.Lock()

    for this.uptr == nil {

    this.cond.Wait()

    }

    this.mux.Unlock()

    }

    func (this *cond) wake(uptr unsafe.Pointer) {

    this.mux.Lock()

    this.uptr = uptr

    this.mux.Unlock()

    this.cond.Broadcast()

    }

    type LeadLock struct {

    nr     int64

    cond   *cond

    holder *cond

    mux    sync.Mutex

    }

    func NewLeadLock() *LeadLock {

    leadlock := &LeadLock{}

    leadlock.cond = newCond()

    return leadlock

    }

    func (this *LeadLock) Lock() unsafe.Pointer {

    var uptr unsafe.Pointer

    n := atomic.AddInt64(&this.nr, 1)

    ptr := (*unsafe.Pointer)(unsafe.Pointer(&this.cond))

    if n > 1 {

    cond := (*cond)(atomic.LoadPointer(ptr))

    cond.wait()

    uptr = cond.uptr

    } else {

    this.mux.Lock()

    atomic.StoreInt64(&this.nr, 0)

    this.holder = (*cond)(atomic.SwapPointer(ptr, unsafe.Pointer(newCond())))

    }

    return uptr

    }

    func (this *LeadLock) Unlock(uptr unsafe.Pointer) {

    ptr := unsafe.Pointer(&this.holder)

    holder := atomic.SwapPointer((*unsafe.Pointer)(ptr), unsafe.Pointer(nil))

    if holder == nil {

    return

    }

    (*cond)(holder).wake(uptr)

    this.mux.Unlock()

    }

    【 在 zylthinking2 的大作中提到: 】

    : 值不值一个360 T7级别

    : 真是心寒了

    : 难道 43 岁就真的要窝窝囊囊被人欺负?

    : ...................

    02月03日
  • 找工作, 大家看一下, 这样的代码水平如何

    值不值一个360 T7级别

    真是心寒了

    难道 43 岁就真的要窝窝囊囊被人欺负?

    居然想给我降 T6

    我艹了

    有没有公司能接收我这样情况的

    人不善于搞人际关系, 不擅长演讲, PPT 这些, 也不擅长面试

    年纪虽然不小了, 但刻苦努力程度比一般人高

    不为别的, 只为手里攒着活就心理难受

    责任心也比一般人高

    属于代码控, 很难接受逻辑无发控制, 或者逻辑凌乱

    这是我写的一篇关于 RCU 的短文

    https://www.cnblogs.com/zylthinking/archive/2013/02/05/2889733.html

    43 岁了, 年龄卡人, 本没太大心气了

    但实在是逼人, 我就拼着现在价值 200 万的股票不要了

    不争包子争口气

    各位贵人看得起的帮扶一把

    02月03日
  • Re: 方形方向盘是未来标配

    所谓自动驾驶只是为了让司机喝茶, 打游戏, 看手机。。。。

    万年不变的陈腔滥调

    这说明再也想不到其他的鼓吹的地方了

    【 在 hondooo 的大作中提到: 】

    : 造型酷炫有科技感只是表象

    : 更重要的是方形方向盘才能完美适配高级自动驾驶

    01月28日
  • Re: 新S果然是“AI换挡”

    这是有病吧

    01月28日
  • Re:【我觉得】ios有一个功能秒杀安卓全家

    唯一优势就是不卡 别说现在21年了什么的

    发自「今日水木 on RVL-AL09」

    【 在 kiwivip 的大作中提到: 】

    : 唯一的优势是更安全

    : --

    01月26日